/******************************************************************************
 * Filename    : SmdServlet.java
 * Author      : LEOH.LEUNG
 * Date Created: 2012-07-16
 * Content     : Definition of ...
 * (c) Copyright XML Asia Limited 2012. All rights reserved.
 * No part of this program may be photocopied reproduced or translated to
 * another program language without prior written consent of XML Asia Limited
 ******************************************************************************/

package com.xmlasia.web.servlet;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.web.servlet.FrameworkServlet;

import com.xmlasia.web.service.smd.SMDService;
import com.xmlasia.web.smd.SMDRequest;
import com.xmlasia.web.smd.SMDResponse;

/**
 * 
 * @author LEOH.LEUNG
 *
 */
public class SmdServlet extends FrameworkServlet {

	private static final long serialVersionUID = 1L;

	private final Logger logger = LoggerFactory.getLogger(SmdServlet.class);
	
	private final ObjectMapper objectMapper = new ObjectMapper();
	
	@Override
	protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String pathInfo = request.getPathInfo();
		String service = StringUtils.substringAfter(pathInfo, "/");
		InputStream is = request.getInputStream();
		String input = IOUtils.toString(is);
		logger.info("service :{}, Input:{}", new Object[]{service,input});
		SMDRequest smdRequest = objectMapper.readValue(input, SMDRequest.class);
		smdRequest.setService(service);
		
		
		SMDService<?> serviceObject = this.getWebApplicationContext().getBean(service, SMDService.class);
		String method = smdRequest.getMethod();
		Map<String, Object> parameters = smdRequest.getParams();
		
		
		Class objectClass = serviceObject.getObjectClass();
		ExpressionParser parser = new SpelExpressionParser();
		Object rootObject = parser.parseExpression("new "+objectClass.getName()+"()").getValue(objectClass);
		for(String key:smdRequest.getParams().keySet()){
			parser.parseExpression(key).setValue(rootObject, smdRequest.getParams().get(key));
		}
		
		EvaluationContext context = new StandardEvaluationContext(serviceObject);
		Expression exp = parser.parseExpression(method+"(#field1)");
		context.setVariable("field1", rootObject);
		SMDResponse smdResponse = exp.getValue(context, SMDResponse.class);
		OutputStream os = response.getOutputStream();
		objectMapper.writeValue(os, smdResponse);
		os.close();
	}

}
